/*
 * Copyright 2002-2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.config;

import java.beans.PropertyEditor;
import java.security.AccessControlContext;

import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.PropertyEditorRegistry;
import org.springframework.beans.TypeConverter;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.HierarchicalBeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.core.convert.ConversionService;
import org.springframework.lang.Nullable;
import org.springframework.util.StringValueResolver;

/**
 * ConfigurableBeanFactory继承了HierarchicalBeanFactory, SingletonBeanRegistry两个接口。这个接口将被大多数bean工厂实现。
 *
 * @author Juergen Hoeller
 * @see org.springframework.beans.factory.BeanFactory
 * @see org.springframework.beans.factory.ListableBeanFactory
 * @see ConfigurableListableBeanFactory
 * @since 03.11.2003
 */
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {

	//单例
	String SCOPE_SINGLETON = "singleton";

	// 多例
	String SCOPE_PROTOTYPE = "prototype";


	/**
	 * 设置父容器
	 */
	void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;

	/**
	 * 设置类加载器
	 */
	void setBeanClassLoader(@Nullable ClassLoader beanClassLoader);

	/**
	 * 获取类加载器
	 */
	@Nullable
	ClassLoader getBeanClassLoader( );

	/**
	 * 设置临时加载器，如果涉及到加载时编织，通常只指定一个临时类装入器，以确保实际的bean类被尽可能延迟地装入
	 */
	void setTempClassLoader(@Nullable ClassLoader tempClassLoader);

	/**
	 * 获取临时加载器
	 */
	@Nullable
	ClassLoader getTempClassLoader( );

	/**
	 * 设置是否缓存
	 * <p>
	 * 每次创建bean都要从类加载器获取信息。
	 */
	void setCacheBeanMetadata(boolean cacheBeanMetadata);

	/**
	 * 获取是否缓存
	 */
	boolean isCacheBeanMetadata( );

	/**
	 * 设置表达式解析器
	 * <p>
	 * 为beanDefinition值中的表达式提供解决策略.默认的BeanFactory里是没有激活的表达式支持的.
	 * 一个ApplicationContext通常会设置一个标准的表达式策略,以一种统一的EL兼容风格支持“#{}”表达式.
	 *
	 * @since 3.0
	 */
	void setBeanExpressionResolver(@Nullable BeanExpressionResolver resolver);

	/**
	 * 获取表达式解析器
	 */
	@Nullable
	BeanExpressionResolver getBeanExpressionResolver( );

	/**
	 * 设置类型转换器
	 */
	void setConversionService(@Nullable ConversionService conversionService);

	/**
	 * 获取类型转换器
	 * <p>
	 * 指定一个Spring3.0 ConversionService来进行属性值的转换,是JavaBean中PropertyEditor的一种替代品.
	 */
	@Nullable
	ConversionService getConversionService( );

	/**
	 * 添加属性编辑器
	 */
	void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);

	/**
	 * 注册给定类型的属性编辑器
	 */
	void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);

	/**
	 * 使用在这个BeanFactory中注册的自定义编辑器初始化给定的PropertyEditorRegistry
	 */
	void copyRegisteredEditorsTo(PropertyEditorRegistry registry);

	/**
	 * 设置类型转换器
	 */
	void setTypeConverter(TypeConverter typeConverter);

	/**
	 * 获取类型转换器
	 */
	TypeConverter getTypeConverter( );

	/**
	 * 为嵌入的值(如注释属性)添加字符串解析器
	 */
	void addEmbeddedValueResolver(StringValueResolver valueResolver);

	boolean hasEmbeddedValueResolver( );

	/**
	 * 解决一个给定的嵌入式的值,例如注解中的属性.
	 */
	@Nullable
	String resolveEmbeddedValue(String value);

	/**
	 * 增加后置处理器
	 */
	void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);

	/**
	 * 获取后置处理器的个数
	 */
	int getBeanPostProcessorCount( );

	/**
	 * 注册作用域
	 */
	void registerScope(String scopeName, Scope scope);

	/**
	 * 获取作用域，除了单例和多例
	 */
	String[] getRegisteredScopeNames( );

	/**
	 * 通过名称获取作用域
	 */
	@Nullable
	Scope getRegisteredScope(String scopeName);

	/**
	 * 获取安全作用域
	 */
	AccessControlContext getAccessControlContext( );

	/**
	 * 配置复制。复制内容包括所有标准配置设置以及beanPostprocessor、
	 * 作用域和特定于工厂的内部设置。不应该包含任何实际bean定义的元数据，
	 * 例如BeanDefinition对象和bean名称别名
	 */
	void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);

	/**
	 * 注册别名
	 */
	void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException;

	/**
	 * 根据valueResolver移除别名
	 */
	void resolveAliases(StringValueResolver valueResolver);

	/**
	 * 合并bean的定义，包括父类继承下来的
	 */
	BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

	/**
	 * 判断给定名字的Bean是否是一个FactoryBean.
	 */
	boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;

	/**
	 * 设置bean是否在创建，循环依赖的时候要靠这个解决
	 */
	void setCurrentlyInCreation(String beanName, boolean inCreation);

	/**
	 * 获取bean是否在创建中
	 */
	boolean isCurrentlyInCreation(String beanName);

	/**
	 * 注册一个指定bean的依赖bean
	 */
	void registerDependentBean(String beanName, String dependentBeanName);

	/**
	 * 获取依赖指定bean的所有bean
	 */
	String[] getDependentBeans(String beanName);

	/**
	 * 获取指定bean的所有依赖
	 */
	String[] getDependenciesForBean(String beanName);

	/**
	 * 销毁指定的bean
	 */
	void destroyBean(String beanName, Object beanInstance);

	/**
	 * 销毁指定scope的bean
	 */
	void destroyScopedBean(String beanName);

	/**
	 * 销毁所有的单例bean
	 */
	void destroySingletons( );

}
